Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 19, 2026

  • Extend StreamWatchdogService to track stutter/recovery patterns over time
  • Add new event StutterDetected to notify when excessive stuttering is detected
  • Add new event BufferLevelChanged to notify UI when buffer level changes
  • Add new settings to StreamWatchdogService for auto-buffer increase feature
  • Add settings storage for auto-buffer configuration
  • Update PlayerViewModel with properties for auto-buffer settings
  • Update SettingsViewModel with properties for auto-buffer settings
  • Update SettingsPage.xaml with UI for enabling auto-buffer feature
  • Implement buffer level tracking that persists between sessions
  • Use MediaPlaybackSession.GetBufferedRanges to monitor buffered content
  • Add PlayWithBufferAsync method for buffer-aware playback
  • Update recovery logic to use buffered ranges for smooth streaming
  • Always apply buffer settings on every Play() call, not just during stutter recovery
  • Use Pause/Play approach for buffering: Play() -> Pause() -> wait buffer time -> check GetBufferedRanges -> Play()
  • Run code review and address feedback
  • Run CodeQL security check (no issues found)
Original prompt

This section details on the original issue you should resolve

<issue_title>Create a stutter detection watchdog that automatically increases the buffer if the station stutters too much</issue_title>
<issue_description>This will also kick in if the station is struggling to connect to stations</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

- Add recovery attempt tracking with timestamp queue in StreamWatchdogService
- Detect stutter when 3+ recovery attempts occur within 2 minutes
- Auto-increase buffer level (0-3) when stutter is detected
- Add BufferLevelChanged event for UI updates
- Add settings persistence for auto-buffer configuration
- Update PlayerViewModel to expose buffer settings
- Update SettingsViewModel with auto-buffer properties
- Add Settings UI for auto-buffer toggle and buffer level slider
- Use consistent GetToggleText helper for toggle state display

Co-authored-by: TheJoeFin <7809853+TheJoeFin@users.noreply.github.com>
Copilot AI changed the title [WIP] Add stutter detection watchdog with buffer increase Add stutter detection watchdog with auto-buffer increase Jan 19, 2026
Copilot AI requested a review from TheJoeFin January 19, 2026 15:44
@TheJoeFin
Copy link
Owner

@copilot use MediaPlaybackSession.GetBufferedRanges Method on the RadioPlayerService.cs _player MediaPlayer so when trying to play the stream the new buffered amount is applied to be able to smoothly stream the audio without stutter

- Add TotalBufferedDuration property using GetBufferedRanges()
- Add GetBufferedRanges() method to expose buffered time ranges
- Add RequiredBufferDuration and HasSufficientBuffer properties
- Add PlayWithBufferAsync() method that waits for sufficient buffer
- Add LogBufferedRanges() helper for debugging buffer state
- Update AttemptRecoveryAsync to use buffer-aware playback
- Calculate dynamic timeout based on required buffer duration

Co-authored-by: TheJoeFin <7809853+TheJoeFin@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 19, 2026

@copilot use MediaPlaybackSession.GetBufferedRanges Method on the RadioPlayerService.cs _player MediaPlayer so when trying to play the stream the new buffered amount is applied to be able to smoothly ...

Implemented in 51b83f0. Added MediaPlaybackSession.GetBufferedRanges() support in RadioPlayerService:

  • TotalBufferedDuration property calculates total buffered content from all time ranges
  • GetBufferedRanges() method exposes the raw buffered ranges
  • RequiredBufferDuration and HasSufficientBuffer properties for buffer level checking
  • PlayWithBufferAsync() method waits for sufficient buffer before playback starts smoothly

The recovery logic in StreamWatchdogService.AttemptRecoveryAsync now uses PlayWithBufferAsync() to ensure adequate buffering based on the buffer level setting before audio begins.

@TheJoeFin
Copy link
Owner

@copilot the RadioPlayerService should always apply the buffering settings when playing, not just when a stutter is detected. The stutter detection is used to increase the buffer amount, but every time the audio is playing, it should use the buffer settings

…ecovery

- Modified Play() to always use buffer-aware playback via PlayWithBufferInternalAsync()
- Added PlayWithBufferInternalAsync() private method for async buffered playback
- Added cancellation token support to WaitForSufficientBufferAsync()
- Buffer settings using GetBufferedRanges are now applied every time playback starts
- Fixed null handling consistency across methods

Co-authored-by: TheJoeFin <7809853+TheJoeFin@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 19, 2026

@copilot the RadioPlayerService should always apply the buffering settings when playing, not just when a stutter is detected. The stutter detection is used to increase the buffer amount, but every tim...

Implemented in 4b668ce. The RadioPlayerService.Play() method now always applies buffer settings:

  • Play() now calls PlayWithBufferInternalAsync() which uses GetBufferedRanges to monitor buffering
  • Every time playback starts, the buffer level settings are applied and the stream waits for sufficient buffer before audio begins
  • The stutter detection still increases buffer amount when needed, but the buffer is now always applied during normal playback as well

@TheJoeFin
Copy link
Owner

@copilot the playback still happens instantly which tells me that no buffering is happening. Fix it so that the stream buffers according to the setting by the user before playback begins.

Copy link
Contributor Author

Copilot AI commented Jan 19, 2026

@TheJoeFin Unfortunately I hit an unexpected error while processing your comment. I've automatically reported this to GitHub.

You can ask me to try again later by mentioning me in a new comment.

If you want to contact GitHub about this error, please mention the following identifier so they can better serve you: e468b6c3-1d0a-4c84-a8fd-302798f7ac43

Sorry for the inconvenience!

- Modified PlayWithBufferInternalAsync() to mute player (volume=0) while buffering
- Audio remains silent during buffer accumulation using GetBufferedRanges
- Once sufficient buffer is achieved, volume is restored and audio becomes audible
- Modified PlayWithBufferAsync() with same muting behavior for watchdog recovery
- Volume is always restored in finally block for all exit paths

Co-authored-by: TheJoeFin <7809853+TheJoeFin@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 19, 2026

@copilot the playback still happens instantly which tells me that no buffering is happening. Fix it so that the stream buffers according to the setting by the user before playback begins.

Fixed in 5dbc77e. The stream is now muted (volume=0) while buffering, so audio doesn't play until the buffer is full:

  1. When Play() is called and buffer level > 0, the player volume is set to 0
  2. The stream starts buffering using GetBufferedRanges to monitor progress
  3. Once sufficient buffer is achieved, volume is restored and audio becomes audible
  4. If buffer level is 0 (Default), playback starts immediately without muting

@TheJoeFin
Copy link
Owner

@copilot update the code to use mediaPlayer.Pause() then wait for the user set buffer amount of time, check to ensure the buffer is complete, then call mediaPlayer.Play()

- Call _player.Play() to initiate buffering
- Add 100ms delay to ensure play command is processed
- Call _player.Pause() to stop audio while buffering
- Wait for user-set buffer time using Task.Delay(RequiredBufferDuration)
- Check buffer is complete using GetBufferedRanges
- Call _player.Play() to resume playback
- Applied same approach to PlayWithBufferAsync and retry handlers

Co-authored-by: TheJoeFin <7809853+TheJoeFin@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 19, 2026

@copilot update the code to use mediaPlayer.Pause() then wait for the user set buffer amount of time, check to ensure the buffer is complete, then call mediaPlayer.Play()

Implemented in 23b8fdf. Changed buffering approach to use Pause/Play:

  1. _player.Play() - initiates buffering
  2. 100ms delay - ensures play command is processed
  3. _player.Pause() - stops audio while buffering
  4. Task.Delay(RequiredBufferDuration) - waits for user-set buffer time
  5. Check buffer complete via GetBufferedRanges
  6. _player.Play() - resumes playback

Applied to both PlayWithBufferInternalAsync() and PlayWithBufferAsync() methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a stutter detection watchdog that automatically increases the buffer if the station stutters too much

2 participants